package com.zdlog.wenjuan.controller.web;

import com.zdlog.wenjuan.VO.ResultBoolenVO;
import com.zdlog.wenjuan.VO.ResultVO;
import com.zdlog.wenjuan.config.EmailConfig;
import com.zdlog.wenjuan.constant.CookieConstant;
import com.zdlog.wenjuan.constant.RedisConstant;
import com.zdlog.wenjuan.dataobject.UserInfo;
import com.zdlog.wenjuan.enums.ResultEnum;
import com.zdlog.wenjuan.exception.SellException;
import com.zdlog.wenjuan.service.UserService;
import com.zdlog.wenjuan.service.WebSocket;
import com.zdlog.wenjuan.util.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.mail.MessagingException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

import static com.zdlog.wenjuan.util.MailUtil.sendMail;

/**
 * @program: wenjuanSer
 * @PACKAGE_NAME: com.zdlog.wenjuan.controller
 * @author: Kuaile
 * @create: 2018-02-04 00:18
 **/



@Controller
@ResponseBody
@Slf4j
public class UserInfoController {


    @Autowired
    private UserService userService;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private EmailConfig emailConfig;




    @GetMapping("/login")
    public ModelAndView loginView() {
        return new ModelAndView("login/loginView");
    }


    @PostMapping("/toLogin")
    public ModelAndView login(@RequestParam(value = "username") String username,
                              @RequestParam(value = "password") String password,
                              HttpServletResponse response,
                              Map<String, Object> map) {
        //1.数据库匹配是否正确

        ResultVO resultVO = userService.login(username, password);
        int code = resultVO.getCode();
        if (code != 0) {
            map.put("msg", resultVO.getMsg());
            map.put("url", "/login");
            return new ModelAndView("common/error");
        }

        //2.设置token、至redis
        String token = UUID.randomUUID().toString();
        Integer expire = RedisConstant.EXPIRE;
        redisTemplate.opsForValue().set(String.format(RedisConstant.TOKEN_PREFIX, token), ((UserInfo)resultVO.getData()).getUserId(), expire, TimeUnit.SECONDS);
        //3.设置token至cookie
        CookieUtil.set(response, CookieConstant.TOKEN, token, CookieConstant.EXPIRE);
        return new ModelAndView("redirect:" +"/form/list");
    }


    /**
     * 注册
     * @param username  用户名
     * @param password 密码
     * @param email  验证码
     * @return
     */

    @PostMapping("/toRegister")
    public ResultBoolenVO register(@RequestParam(value = "username") String username,
                                   @RequestParam(value = "password") String password,
                                   @RequestParam(value = "code") String code,
                                   @RequestParam(value = "email") String email) {
        if (userService.checkEmail(email)) {
            return ResultBoolenVOUtil.error(ResultEnum.EMAIL_EXIST_ERROR.getMessage());
        }
        if (userService.checkName(username)) {
            return ResultBoolenVOUtil.error(ResultEnum.USER_USERNAME_EXIST.getMessage());
        }
        //去redis里查询
        String codeValue = redisTemplate.opsForValue().get(String.format(RedisConstant.CODE_PREFIX, email));
        if (code.equals(codeValue)) {
            UserInfo userInfo = new UserInfo();
            userInfo.setUserId(KeyUtil.genUniqueKey());
            userInfo.setUsername(username);
            userInfo.setPassword(password);
            userInfo.setEMail(email);
            return userService.register(userInfo);
        } else {
            return ResultBoolenVOUtil.error(ResultEnum.EMAIL_EQUEST_ERROR.getMessage());
        }
    }


    /**
     * 用户信息页面
     * @return
     */
    @GetMapping("/userInfo")
    public ModelAndView userInfo() {
        return new ModelAndView("user/list");
    }


    /**
     * 退出登录
     * @param request
     * @param response
     * @param map
     * @return
     */
    @PostMapping("/logout")
    public ResultBoolenVO logout(HttpServletRequest request,
                               HttpServletResponse response,
                               Map<String, Object> map) {
        //1. 从cookie里查询
        Cookie cookie = CookieUtil.get(request, CookieConstant.TOKEN);
        if (cookie != null) {
            //2. 清除redis
            redisTemplate.opsForValue().getOperations().delete(String.format(RedisConstant.TOKEN_PREFIX, cookie.getValue()));

            //3. 清除cookie
            CookieUtil.set(response, CookieConstant.TOKEN, null, 0);
        }

        map.put("msg", ResultEnum.LOGOUT_SUCCESS.getMessage());
        map.put("url", "/form/list");
        return ResultBoolenVOUtil.success();
    }


    /**
     * 发送验证码
     * @param email  接收验证码的邮箱
     * @return
     */
    @GetMapping("/getcode")
    public ResultVO  sendRegister(@RequestParam(value = "email") String email) {
        String code = String.valueOf((int) ((Math.random() * 9 + 1) * 100000));
        //1.发送邮件
        try {
            sendMail(email, "问卷系统注册验证码", "你好，问卷调查系统的验证码为：\n"+code, null,emailConfig);
        } catch (MessagingException e) {
            throw new SellException(ResultEnum.EMAIL_SEND_ERROR);
        } catch (UnsupportedEncodingException e) {
            throw new SellException(ResultEnum.EMAIL_SEND_ERROR);
        }
        //2.验证码保存到redis
        Integer expire = RedisConstant.EMAIL_EXPIRE;
        redisTemplate.opsForValue().set(String.format(RedisConstant.CODE_PREFIX, email), code, expire, TimeUnit.SECONDS);
        return ResultVOUtil.success();

    }



    @GetMapping("/register")
    public ModelAndView registerView() {
        return new ModelAndView("login/register");
    }



   @ PostMapping("/checkname")
    public ResultBoolenVO checkNmae(@RequestParam(value = "username") String username) {
       if (userService.checkName(username)) {
           return ResultBoolenVOUtil.error("用户名已存在");
       }
       return ResultBoolenVOUtil.success();
    }


    @ PostMapping("/checkemail")
    public ResultBoolenVO checkEmail(@RequestParam(value = "email") String email) {
        if (userService.checkEmail(email)) {
            return ResultBoolenVOUtil.error("此邮箱已被注册");
        }
        return ResultBoolenVOUtil.success();
    }

}
